package io.github.uicdb.et.data.recipe;

import com.google.common.collect.Lists;
import io.github.uicdb.et.ModElements;
import io.github.uicdb.et.element.BasicElement;
import io.github.uicdb.et.recipe.ElementRecipe;
import io.github.uicdb.et.recipe.ElementRecipePart;
import lombok.AccessLevel;
import lombok.RequiredArgsConstructor;
import net.minecraft.advancements.Criterion;
import net.minecraft.core.Holder;
import net.minecraft.data.recipes.RecipeBuilder;
import net.minecraft.data.recipes.RecipeOutput;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.tags.TagKey;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.Ingredient;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.List;

@RequiredArgsConstructor(staticName = "of",access = AccessLevel.PRIVATE)
public class ElementRecipeBuilder implements RecipeBuilder {
    final List<Ingredient> items;
    final List<ElementRecipePart> input;
    final ItemStack result;

    public static ElementRecipeBuilder ofResult(ItemStack result) {
        return new ElementRecipeBuilder(Lists.newArrayList(), Lists.newArrayList(), result);
    }

    public static ElementRecipeBuilder ofResult(Item result) {
        return new ElementRecipeBuilder(Lists.newArrayList(), Lists.newArrayList(), result.getDefaultInstance());
    }

    public ElementRecipeBuilder input(Holder<BasicElement> holder, int amount) {
        input.add(new ElementRecipePart(holder, amount));
        return this;
    }
    public ElementRecipeBuilder input(ModElements elements, int amount) {
        input.add(new ElementRecipePart(elements.holder(), amount));
        return this;
    }
    public ElementRecipeBuilder input(ItemStack stack) {
        items.add(Ingredient.of(stack));
        return this;
    }
    public ElementRecipeBuilder input(Ingredient ingredient) {
        items.add(ingredient);
        return this;
    }
    public ElementRecipeBuilder input(TagKey<Item> tagKey) {
        items.add(Ingredient.of(tagKey));
        return this;
    }
    public ElementRecipeBuilder input(Item stack, int amount) {
        items.add(Ingredient.of(new ItemStack(stack, amount)));
        return this;
    }

    public ElementRecipeBuilder input(Item item) {
        items.add(Ingredient.of(item));
        return this;
    }

    @Override
    public @NotNull RecipeBuilder unlockedBy(@NotNull String s, Criterion<?> criterion) {
        return this;
    }

    @Override
    public @NotNull RecipeBuilder group(@Nullable String s) {
        return this;
    }

    @Override
    public Item getResult() {
        return result.getItem();
    }


    @Override
    public void save(RecipeOutput recipeOutput, @NotNull ResourceLocation resourceLocation) {
        ElementRecipe elementRecipe = new ElementRecipe(input, items, result);
        recipeOutput.accept(resourceLocation, elementRecipe, null);
    }
}
